package com.och.mrcp.core.mrcp.model;

import lombok.Data;
import lombok.EqualsAndHashCode;



/**
 * MRCPv2响应消息
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class MrcpResponse extends MrcpMessage {
    
    // 响应状态码
    public enum StatusCode {
        // 成功状态码（MRCP常用语义：COMPLETE）
        SUCCESS(200, "COMPLETE"),
        
        // 客户端错误状态码
        BAD_REQUEST(400, "Bad Request"),
        UNAUTHORIZED(401, "Unauthorized"),
        FORBIDDEN(403, "Forbidden"),
        NOT_FOUND(404, "Not Found"),
        METHOD_NOT_ALLOWED(405, "Method Not Allowed"),
        METHOD_OR_OPERATION_FAILED(407, "Method or Operation Failed"),
        REQUEST_TIMEOUT(408, "Request Timeout"),
        CONFLICT(409, "Conflict"),
        UNSUPPORTED_MEDIA_TYPE(415, "Unsupported Media Type"),
        
        // 服务器错误状态码
        INTERNAL_SERVER_ERROR(500, "Internal Server Error"),
        NOT_IMPLEMENTED(501, "Not Implemented"),
        SERVICE_UNAVAILABLE(503, "Service Unavailable");
        
        // 添加Cairo项目中使用的MRCP标准状态码
        public static final short STATUS_SUCCESS = 200;
        public static final short STATUS_SERVER_INTERNAL_ERROR = 500;
        
        private final int code;
        private final String reason;
        
        StatusCode(int code, String reason) {
            this.code = code;
            this.reason = reason;
        }
        
        public int getCode() {
            return code;
        }
        
        public String getReason() {
            return reason;
        }
        
        public static StatusCode fromCode(int code) {
            for (StatusCode status : values()) {
                if (status.code == code) {
                    return status;
                }
            }
            throw new IllegalArgumentException("Unknown status code: " + code);
        }
    }
    
    private StatusCode statusCode;
    private String statusReason;
    private String requestId;  // 添加requestId字段
    
    public MrcpResponse() {
        super();
        this.messageType = MessageType.RESPONSE;
    }
    
    public MrcpResponse(ResourceType resourceType, StatusCode statusCode) {
        this();
        this.resourceType = resourceType;
        this.statusCode = statusCode;
        this.statusReason = statusCode.getReason();
    }
    
    @Override
    public boolean isValid() {
        return resourceType != null && 
               statusCode != null && 
               messageId != null && 
               !messageId.isEmpty();
    }
    
    @Override
    public String encode() {
        StringBuilder sb = new StringBuilder();
        
        // 先构建头部和消息体部分以获得准确的长度
        StringBuilder headerAndBody = new StringBuilder();
        
        // 头部字段（按固定顺序添加，确保一致性）
        // 1. 先添加 Channel-Identifier（如果存在）
        String channelId = getHeader("Channel-Identifier");
        if (channelId != null) {
            headerAndBody.append("Channel-Identifier: ").append(channelId).append("\r\n");
        }
        
        // 2. 添加 Completion-Cause（如果存在）
        String completionCause = getHeader("Completion-Cause");
        if (completionCause != null) {
            headerAndBody.append("Completion-Cause: ").append(completionCause).append("\r\n");
        }
        
        // 3. 添加其他头部字段
        headers.forEach((name, value) -> {
            if (!"Channel-Identifier".equals(name) && !"Completion-Cause".equals(name)) {
                headerAndBody.append(name).append(": ").append(value).append("\r\n");
            }
        });
        
        // 空行分隔头部和消息体
        headerAndBody.append("\r\n");
        
        // 消息体
        if (body != null && !body.isEmpty()) {
            headerAndBody.append(body);
        }
        
        // 计算消息长度：对于标准错误响应（只有基本头部字段），使用0
        int messageLength = 0;
        String headerAndBodyStr = headerAndBody.toString();
        
        // 检查是否只包含标准头部字段（Channel-Identifier, Completion-Cause）且无消息体
        boolean isStandardErrorResponse = (body == null || body.isEmpty()) && 
                                        headers.size() <= 2 && 
                                        (headers.containsKey("Channel-Identifier") || headers.containsKey("Completion-Cause"));
        
        if (!isStandardErrorResponse) {
            // 非标准错误响应，计算实际长度
            try {
                messageLength = headerAndBodyStr.getBytes("UTF-8").length;
            } catch (Exception e) {
                messageLength = headerAndBodyStr.length();
            }
        }
        // 否则保持messageLength = 0
        
        // 第一行：MRCP版本 + 消息长度 + 请求ID + 状态码 + 请求状态
        sb.append("MRCP/").append(MRCP_VERSION).append(" ")
          .append(messageLength).append(" ")
          .append(requestId != null ? requestId : "0").append(" ")
          .append(statusCode != null ? statusCode.getCode() : 200).append(" ")
          .append(getRequestState() != null ? getRequestState() : "COMPLETE").append("\r\n");
        
        // 添加头部和消息体
        sb.append(headerAndBody);
        
        return sb.toString();
    }
    

    
    @Override
    public String getMessageTypeDescription() {
        return "MRCPv2 Response: " + (statusCode != null ? statusCode.getCode() : "UNKNOWN");
    }
    
    /**
     * 设置状态码
     */
    public void setStatusCode(StatusCode statusCode) {
        this.statusCode = statusCode;
        this.statusReason = statusCode.getReason();
        // 同时设置父类的状态码字段
        super.setStatusCode(statusCode.getCode());
    }
    
    /**
     * 设置自定义状态原因
     */
    public void setStatusReason(String reason) {
        this.statusReason = reason;
    }
    
    /**
     * 重写父类的getStatusCode方法，返回枚举类型
     */
    @Override
    public int getStatusCode() {
        return statusCode != null ? statusCode.getCode() : 0;
    }
    
    /**
     * 获取状态码枚举
     */
    public StatusCode getStatusCodeEnum() {
        return statusCode;
    }
    
    /**
     * 设置请求ID
     */
    public void setRequestId(String requestId) {
        this.requestId = requestId;
    }
    
    /**
     * 获取请求ID
     */
    public String getRequestId() {
        return requestId;
    }
}
